//
//  IAPHelper.m
//  InAppRage
//
//  Created by Ray Wenderlich on 2/28/11.
//  Copyright 2011 Ray Wenderlich. All rights reserved.
//

#import "IAPHelper.h"
#import "GTMBase64.h"
//#import "WSJSON.h"
//#import "RechargeViewController.h"
#import "DB_UnComfirmIAPOrderForm.h"
//#import "RechargeCellNode.h"
//#import "WSRechargeCellNode.h"
#import <objc/runtime.h>

#define SubmmitSeconds  30
static IAPHelper *gInstance = nil;
static NSMutableData *webData= nil;

@interface IAPHelper(Private)
- (void)submitRecharg2ServerWithReciep:(NSDictionary *)receiptArg
                             productID:(NSString *)productIDArg
                             buyNumber:(NSInteger)buyNumberArg
                              recordID:(NSInteger)recordIDArg;
- (void)timerSubmitMethod:(NSTimer*)theTimer;
@end

@implementation IAPHelper
@synthesize productIdentifiers = _productIdentifiers;
@synthesize packageProductIdentifiers = _packageProductIdentifiers;
@synthesize products = _products;
@synthesize request = _request;
@synthesize iapDelegate = _iapDelegate;
@synthesize productIDwithMoney = _productIDwithMoney;


- (id)init
{
    if ((self = [super init]))
    {
        _payOrderNo=@"";
        _productIdentifiers = [[NSMutableSet alloc] init];
        _packageProductIdentifiers = [[NSMutableSet alloc] init];
        _productIDStack = [[NSMutableArray alloc] init];
        _productIDwithMoney = [[NSMutableDictionary alloc] initWithCapacity:0];
        _bGettingProducts = NO;
        _products = [[NSMutableArray alloc] initWithCapacity:0];
        self.appProductIDArray=[[NSArray alloc] init];
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    }
    
    //[NSTimer scheduledTimerWithTimeInterval: SubmmitSeconds target:self selector:@selector(timerSubmitMethod:) userInfo:nil repeats:YES];
    //添加官方充值完成的通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(receiveAppstoreRechargeData:) name:kNotificationAppstoreRechargeFininsh object:nil];
    return self;
}
+ (IAPHelper *)sharedInstance
{
    if(nil == gInstance)
    {
        gInstance = [[IAPHelper alloc] init];
    }
    return gInstance;
}

- (void)receiveAppstoreRechargeData:(NSNotification *)nofication
{
    NSDictionary *dic = [nofication userInfo];
    NSString *recordID = [dic objectForKey:@"transacton_id"];
    
    if (0 == [[dic objectForKey:@"result"] intValue])
    {
        [[DB_UnComfirmIAPOrderForm shareInstance] deleteReceipWithID:[recordID intValue]];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:kSucceedRechargeNotification object:self];
    }
    else
    {
        NSLog(@"recharge result code : %@", [dic objectForKey:@"result"]);
        [[DB_UnComfirmIAPOrderForm shareInstance] updateRecharge_resultWithRecordID:[recordID intValue]
                                                                              Value:0];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:kFailedRechargeNotification object:self userInfo:[NSDictionary dictionaryWithObject:@"result code : %@" forKey:@"error"]];
    }
}
//获取苹果商品列表
- (void)requestProducts
{
    @synchronized(self)
    {
        if (_bGettingProducts)
        {
            return;
        }
        if ([_products count] != 0) {
            if (self.iapDelegate != nil && [self.iapDelegate respondsToSelector:@selector(getProductsWithResultSuccess:error:)])
            {
                [self.iapDelegate getProductsWithResultSuccess:YES error:nil];
            }
            
            return;
        }
        _bGettingProducts = YES;
    }
    
    if (self.appProductIDArray&&[self.appProductIDArray count]>0) {
        NSMutableSet *allProductID = [[NSMutableSet alloc] initWithArray:self.appProductIDArray];
        self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:allProductID];
        _request.delegate = self;
        [_request start];
    }

}

#pragma mark SKProductsRequestDelegate function
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    
    NSLog(@"Received products results...%lu ---- %lu", (unsigned long)[response.products count], (unsigned long)[response.invalidProductIdentifiers count]);
    
    [self.products addObjectsFromArray:response.products];
    self.request = nil;
    
    @synchronized(self)
    {
        _bGettingProducts = NO;
    }  
    if (self.iapDelegate != nil && [self.iapDelegate respondsToSelector:@selector(getProductsWithResultSuccess:error:)])
    {
        [self.iapDelegate getProductsWithResultSuccess:YES error:nil];
    }
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    @synchronized(self)
    {
        _bGettingProducts = NO;
    }
    NSLog(@"SKRequest error=%@", error.description);
    //  [[NSNotificationCenter defaultCenter] postNotificationName:kProductsRequestFailNotification object:error];
    if (self.iapDelegate != nil && [self.iapDelegate respondsToSelector:@selector(getProductsWithResultSuccess:error:)])
    {
        [self.iapDelegate getProductsWithResultSuccess:NO error:error];
    }
}

- (void)requestDidFinish:(SKRequest *)request
{
    @synchronized(self)
    {
        _bGettingProducts = NO;
    }
    NSLog(@"Request %@ Finish.", request);
}


/**
 *  在交易成功的结果发送到服器
 *
 *  @param receiptArg   接收的凭证
 *  @param productIDArg 产品ID
 *  @param buyNumberArg 付款数
 *  @param recordIDArg  交易id
 */
- (void)submitRecharg2ServerWithReciep:(NSDictionary *)receiptArg
                             productID:(NSString *)productIDArg
                             buyNumber:(NSInteger)buyNumberArg
                              recordID:(NSInteger)recordIDArg
{
    
    
    if (self.payOrderNo&&[self.payOrderNo length]==0) {
        [[DB_UnComfirmIAPOrderForm shareInstance] updateRecharge_resultWithRecordID:recordIDArg Value:0];
        return;
    }
    
    /**上传处理
    SystemUser *mod=[SystemUser shareInstance];
    NSMutableDictionary *params=[NSMutableDictionary dictionaryWithCapacity:0];
    [params addEntriesFromDictionary:[mod GetRequestParamsWithUidAndToken]];
    [params setValue:receiptArg forKey:@"apple_pay_info"];
    [params setValue:self.payOrderNo forKey:@"order_no"];
   
    
    [[CZServiceManager shareInstance] requestServiceWithDictionary:params requestServiceType:CZServiceApplyPay completed:^(NSDictionary *userInfo) {
        if ([[userInfo objectForKey:@"flag"] isEqualToString:@"0"]) {
            [[DB_UnComfirmIAPOrderForm shareInstance] deleteReceipWithID:recordIDArg];
        }else{
            [[DB_UnComfirmIAPOrderForm shareInstance] updateRecharge_resultWithOrderNo:self.payOrderNo value:0 recordID:recordIDArg];
        }
    }];
     
     **/
}

/**
- (void)uploadHandler{
    if (![KHUtil isHasNetWork]) {
        return;
    }
    SystemUser *mod=[SystemUser shareInstance];
    if ([mod isLogin]) {
        
        NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithCapacity:5];
        BOOL ifThereIsRecord = [[DB_UnComfirmIAPOrderForm shareInstance] getRecord:dict];
        
        NSData *receip;
        NSInteger recordID;
        //NSString *productID;
        //NSInteger quantity;
        NSString *orderNo;
        
        if (ifThereIsRecord)
        {
            orderNo=[dict objectForKey:@"order_no"];
            receip = [dict objectForKey:@"receip"];
            //trandId=[dict objectForKey:@"transacton_id"];
            recordID = [[dict objectForKey:@"record_id"] intValue];
            //productID = [dict objectForKey:@"productID"];
            //quantity = [[dict objectForKey:@"quantity"] intValue]; //购买数量
            
            NSDictionary *jsonObject=[NSJSONSerialization
                                      JSONObjectWithData:receip
                                      options:NSJSONReadingMutableLeaves
                                      error:nil];
            
            //[self submitRecharg2ServerWithReciep:jsonObject productID:productID buyNumber:quantity recordID:recordID];
            
            
            SystemUser *mod=[SystemUser shareInstance];
            NSMutableDictionary *params=[NSMutableDictionary dictionaryWithCapacity:0];
            [params addEntriesFromDictionary:[mod GetRequestParamsWithUidAndToken]];
            [params setValue:jsonObject forKey:@"apple_pay_info"];
            [params setValue:orderNo forKey:@"order_no"];
            //上传处理
             [[CZServiceManager shareInstance] requestServiceWithDictionary:params requestServiceType:CZServiceApplyPay completed:^(NSDictionary *userInfo) {
             if ([[userInfo objectForKey:@"flag"] isEqualToString:@"0"]) {
                [[DB_UnComfirmIAPOrderForm shareInstance] deleteReceipWithID:recordID];
             }
             else if ([[userInfo objectForKey:@"flag"] isEqualToString:@"5005"]){ //找不到订单
                 [[DB_UnComfirmIAPOrderForm shareInstance] deleteReceipWithID:recordID];
             }
             else if ([[userInfo objectForKey:@"flag"] isEqualToString:@"2026"]){ //订单状态错误
                 [[DB_UnComfirmIAPOrderForm shareInstance] deleteReceipWithID:recordID];
             }
             else
             {
                [[DB_UnComfirmIAPOrderForm shareInstance] updateRecharge_resultWithRecordID:recordID Value:0];
               }
             }];
            
            
        }
    }
}
 
 **/

- (void)timerSubmitMethod:(NSTimer*)theTimer
{
    NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithCapacity:5];
    BOOL ifThereIsRecord = [[DB_UnComfirmIAPOrderForm shareInstance] getRecord:dict];
    
    NSData *receip;
    NSInteger recordID;
    NSString *productID;
    NSInteger quantity;
    //NSString *trandId;

    if (ifThereIsRecord)
    {
        receip = [dict objectForKey:@"receip"];
        //trandId=[dict objectForKey:@"transacton_id"];
        recordID = [[dict objectForKey:@"record_id"] intValue];
        productID = [dict objectForKey:@"productID"];
        quantity = [[dict objectForKey:@"quantity"] intValue]; //购买数量
        
        NSDictionary *jsonObject=[NSJSONSerialization
                                  JSONObjectWithData:receip
                                  options:NSJSONReadingMutableLeaves
                                  error:nil];
        
        [self submitRecharg2ServerWithReciep:jsonObject productID:productID buyNumber:quantity recordID:recordID];
        
        //[self submitRecharg2ServerWithReciep:[[NSString alloc]initWithData:receip encoding:NSASCIIStringEncoding] productID:productID buyNumber:quantity recordID:recordID];
    }
}

- (void)recordTransaction:(SKPaymentTransaction *)transaction
{    
    // TODO: Record the transaction on the server side...
#if 1
    
    /**
     NSData *receipt = nil;
    if ([[[UIDevice currentDevice] systemVersion] floatValue]>7.0) {
        NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
        receipt =[GTMBase64 encodeData:[NSData dataWithContentsOfURL:receiptURL]];
    }else{
       receipt = [GTMBase64 encodeData:transaction.transactionReceipt];
    }
     **/
     NSData *receipt = [GTMBase64 encodeData:transaction.transactionReceipt];
    
    
    NSString *productID = [_productIDStack lastObject];
    if (productID)
    {
        [_productIDStack removeLastObject];
    }
    
    
    //对象转换成字典
    NSDictionary *jsonDic=[self entityToDictionary:transaction];
    if (jsonDic&&[jsonDic count]>0) {
        NSMutableDictionary *tempDic=[NSMutableDictionary dictionaryWithDictionary:jsonDic];
        NSDictionary *payDic=[self entityToDictionary:transaction.payment];
        if (payDic&&[payDic count]>0) {
            [tempDic setValue:payDic forKey:@"payment"];
        }
        [tempDic setValue:[[NSString alloc]initWithData:receipt encoding:NSASCIIStringEncoding] forKey:@"transactionReceipt"];
        
        //将字典转换成NSData
        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tempDic options:NSJSONWritingPrettyPrinted error: &error];
        NSMutableData *tempJsonData = [NSMutableData dataWithData:jsonData];
        
        //保存在数据库
        NSInteger recordID = [[DB_UnComfirmIAPOrderForm shareInstance] insertReceip:tempJsonData
                                                                            brandID:@"cool"
                                                                          productID:productID
                                                                           quantity:1
                                                                        trasactonID:transaction.transactionIdentifier];
        
        //上传到服务器
        [self submitRecharg2ServerWithReciep:tempDic
                                   productID:productID
                                   buyNumber:1
                                    recordID:recordID];
    }
    
    
   
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; //  只要存入数据库，就可以结束此次交易。
    
    
    
    
#else // sandbox test
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; //  只要存入数据库，就可以结束此次交易。
    
    NSURL *url = [[NSURL alloc] initWithString: @"https://sandbox.itunes.apple.com/verifyReceipt"];
    
    //    NSURL *url = [[NSURL alloc] initWithString: @"https://buy.itunes.apple.com/verifyReceipt"];
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setTimeoutInterval:120.0];
    [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
    
    NSString *receiptStr = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", [GTMBase64  stringByEncodingData:transaction.transactionReceipt]];
    [request setHTTPBody:[receiptStr dataUsingEncoding:NSASCIIStringEncoding]];
    NSLog(@"%@", receiptStr);
    
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding: NSUTF8StringEncoding];
    
    //NSMutableDictionary *returnDic = [NSMutableDictionary dictionary] ;
    //[returnDic setDictionary:[responseString JSONValue]];
    //NSLog(@"%@", returnDic);
#endif
}

- (void)provideContent:(NSString *)productIdentifier {
    
    NSLog(@"Toggling flag for: %@", productIdentifier);
    //[CacheDataUtil setBool:TRUE forKey:productIdentifier];
    NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
    [userDefaults setBool:YES forKey:productIdentifier];
    [userDefaults synchronize];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier];
    
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {
    
    NSLog(@"completeTransaction...");
    
    [self recordTransaction:transaction];
    [self provideContent:transaction.payment.productIdentifier];
}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
    if ([_productIDStack count] != 0)
    {
        [_productIDStack removeLastObject];
    }
    
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

- (void)failedTransaction:(SKPaymentTransaction *)transaction {
    
    // 移出队列
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    if ([_productIDStack count] != 0)
    {
        [_productIDStack removeLastObject];
    }
    
    if(transaction.error.code != SKErrorPaymentCancelled) {
        //WSLog(@"购买失败:%@", transaction.error.localizedDescription);
    } else {
       // WSLog(@"用户取消交易");
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction];
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchasing:
                //WSLog(@"---Purchasing");
                break;
            default:
                // do nothing
                break;
        }
    }
}

- (void)buyProduct:(SKProduct *)product {
    
    NSLog(@"Buying %@...", product.productIdentifier);
    SKPayment *payment = [SKPayment paymentWithProduct:product];
    
    [[SKPaymentQueue defaultQueue] addPayment:payment];
    [_productIDStack addObject:product.productIdentifier];
}

#pragma mark
#pragma mark- NSURLConnectionDelegate
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if (connection == _rechargeTestConnection)
    {
        webData = [[NSMutableData alloc] initWithCapacity:0];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if(connection == _rechargeTestConnection)
    {
        [webData appendData:data];
    }
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSString *jsonValue=[[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];
    
  
    NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:webData options:NSJSONReadingMutableContainers error: nil];
    
    NSMutableDictionary *returnDic = [NSMutableDictionary dictionaryWithCapacity:0];
    [returnDic setDictionary:jsonDic];
    NSLog(@"returnDic = %@",jsonValue);
    NSString *recordID = [returnDic objectForKey:@"transacton_id"];
    
    int nRet = [[returnDic objectForKey:@"result"]intValue];
    switch (nRet)
    {
        case 1:
        {
            [[DB_UnComfirmIAPOrderForm shareInstance] deleteReceipWithID:[recordID intValue]];
            
            [[NSNotificationCenter defaultCenter] postNotificationName:kSucceedRechargeNotification
                                                                object:self];
        }
            break;
        default:
        {
            NSLog(@"recharge result code : %d", nRet);
            [[DB_UnComfirmIAPOrderForm shareInstance] updateRecharge_resultWithRecordID:[recordID intValue]
                                                                                  Value:0];
            
            [[NSNotificationCenter defaultCenter]
             postNotificationName:kFailedRechargeNotification
             object:self
             userInfo:[NSDictionary dictionaryWithObject:@"result code : %@" forKey:@"error"]];
        }
            break;
    }
}

#pragma mark -私有方法
/**
 *  对象转换成属性
 *
 *  @param entity 要转换的对象
 *
 *  @return
 */
-(NSDictionary *) entityToDictionary:(id)entity
{
    
    Class clazz = [entity class];
    u_int count;
    
    objc_property_t* properties = class_copyPropertyList(clazz, &count);
    NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];
    NSMutableArray* valueArray = [NSMutableArray arrayWithCapacity:count];
    
    for (int i = 0; i < count ; i++)
    {
        objc_property_t prop=properties[i];
        const char* propertyName = property_getName(prop);
        
        [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
        
        //        const char* attributeName = property_getAttributes(prop);
        //        NSLog(@"%@",[NSString stringWithUTF8String:propertyName]);
        //        NSLog(@"%@",[NSString stringWithUTF8String:attributeName]);
        id value = [entity valueForKey:[NSString stringWithUTF8String:propertyName]];
        
        
        //id value =  [entity performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];
        if(value ==nil)
            [valueArray addObject:[NSNull null]];
        else {
            
            if ([value isKindOfClass:[NSDate class]]) {
                [valueArray addObject:[NSString stringWithFormat:@"%@",value]];
                
            }else{
              [valueArray addObject:value];
            }
            
            
        }
        //        NSLog(@"%@",value);
    }
    
    free(properties);
    
    NSDictionary* returnDic = [NSDictionary dictionaryWithObjects:valueArray forKeys:propertyArray];
    //NSLog(@"%@", returnDic);
    
    return returnDic;
}
@end
